from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.openapi.utils import get_openapi
# 在最开始就导入并加载环境变量
import os
from dotenv import load_dotenv

# 在最早期加载环境变量
load_dotenv()

from app.core.logging_config import setup_logging
import logging
from app.utils.exception_handler import setup_exception_handlers
from app.utils.response_utils import ResponseResult
from app.core.config import settings
from app.routers import auth_router, upload_router, file_router, chunk_upload_router, directory_router, backup_router
from app.database.database import engine, Base
from app.tasks.cleanup_task import start_cleanup_scheduler
from app.tasks.backup_task import setup_backup_scheduler, shutdown_backup_scheduler
from app.utils.bloom_filter import file_hash_filter

# 设置日志配置
logger = setup_logging()
logger.info("应用初始化开始")
logger.info(f"环境变量加载状态: DATABASE_URL={'已配置' if os.getenv('DATABASE_URL') else '未配置'}")

# 初始化 MinIO 客户端
import app.utils.minio_client  # 先导入模块，确保模块级代码执行
from app.utils.minio_client import get_minio_client
minio_client = get_minio_client()  # 获取已初始化的实例
logger.info("MinIO 客户端初始化完成")

# 初始化数据库
from app.database.database import engine
from app.database import models
models.Base.metadata.create_all(bind=engine)
logger.info("数据库表创建完成")

# 创建 FastAPI 应用实例，添加更多元数据
app = FastAPI(
    title="文件服务 API",
    description="""
    文件服务系统 API。
    
    ## 认证
    
    大部分API需要通过认证才能访问。请点击右上角的"Authorize"按钮使用您的用户名和密码进行认证。
    
    ## 文件上传
    
    系统支持两种上传方式：
    1. 普通上传：适用于小文件（<50MB）
    2. 分片上传：适用于大文件，支持断点续传
    """,
    version="0.2.1",
    docs_url="/docs",
    redoc_url="/redoc",
    openapi_url="/openapi.json",
    openapi_tags=[
        {"name": "认证", "description": "用户认证相关接口"},
        {"name": "文件管理", "description": "文件管理相关接口"},
        {"name": "文件上传", "description": "文件上传相关接口"}
    ]
)

# 设置全局异常处理器
setup_exception_handlers(app)
logger.info("全局异常处理器设置完成")

# 添加安全配置
app.openapi_schema = None  # 清除现有的 OpenAPI schema

def custom_openapi():
    if app.openapi_schema:
        return app.openapi_schema
    
    openapi_schema = get_openapi(
        title=app.title,
        version=app.version,
        description=app.description,
        routes=app.routes,
    )
    
    # 修改安全定义
    openapi_schema["components"]["securitySchemes"] = {
        "OAuth2PasswordBearer": {
            "type": "oauth2",
            "flows": {
                "password": {
                    "tokenUrl": "/auth/oauth/token",
                    "scopes": {}
                }
            }
        }
    }
    
    # 添加统一响应格式示例
    openapi_schema["components"]["schemas"]["StandardResponse"] = {
        "type": "object",
        "properties": {
            "code": {
                "type": "integer",
                "example": 200
            },
            "message": {
                "type": "string",
                "example": "操作成功"
            },
            "data": {
                "type": "object",
                "example": {}
            },
            "timestamp": {
                "type": "string",
                "format": "date-time",
                "example": "2024-03-14T10:00:00.000Z"
            }
        }
    }
    
    # 文件上传响应示例
    openapi_schema["components"]["schemas"]["FileUploadResponse"] = {
        "allOf": [
            {"$ref": "#/components/schemas/StandardResponse"},
            {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "file_id": {"type": "integer", "example": 1},
                            "filename": {"type": "string", "example": "example.jpg"},
                            "original_filename": {"type": "string", "example": "photo.jpg"},
                            "storage_path": {"type": "string", "example": "1/photo/2024/03/14/example_12345678.jpg"},
                            "size": {"type": "integer", "example": 1024},
                            "content_type": {"type": "string", "example": "image/jpeg"},
                            "file_type": {"type": "string", "example": "photo"},
                            "create_time": {"type": "string", "format": "date-time"},
                            "hash": {"type": "string", "example": "sha256hash"},
                            "is_duplicate": {"type": "boolean", "example": False}
                        }
                    }
                }
            }
        ]
    }
    
    # 断点上传响应示例
    openapi_schema["components"]["schemas"]["ChunkUploadInitResponse"] = {
        "allOf": [
            {"$ref": "#/components/schemas/StandardResponse"},
            {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "task_id": {"type": "string", "example": "550e8400-e29b-41d4-a716-446655440000"},
                            "upload_id": {"type": "string", "example": "VXBsb2FkIElEIGZvciA1oc..."},
                            "chunk_size": {"type": "integer", "example": 5242880},
                            "total_chunks": {"type": "integer", "example": 10},
                            "expires_at": {"type": "string", "format": "date-time"}
                        }
                    }
                }
            }
        ]
    }
    
    app.openapi_schema = openapi_schema
    return app.openapi_schema

app.openapi = custom_openapi

# 配置CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 注册路由
app.include_router(auth_router.router)
app.include_router(upload_router.router)
app.include_router(file_router.router)
app.include_router(chunk_upload_router.router)
app.include_router(directory_router.router)
app.include_router(backup_router.router)

@app.get("/", include_in_schema=False)
async def root():
    return {"message": "文件服务 API"}

@app.on_event("startup")
async def startup_event():
    """应用启动时执行的操作"""
    logger.info("应用启动中...")
    
    # 启动文件清理调度器
    start_cleanup_scheduler()
    
    # 启动备份任务调度器
    setup_backup_scheduler()
    
    # 从数据库初始化布隆过滤器
    from app.database.database import get_db
    db = next(get_db())
    try:
        logger.info("正在初始化文件哈希布隆过滤器...")
        
        # 加载到布隆过滤器
        file_hash_filter.load_from_database(db)
        logger.info("布隆过滤器初始化完成")
        
    except Exception as e:
        logger.error(f"布隆过滤器初始化失败: {str(e)}")
    finally:
        db.close()
    
    # 应用启动完成
    logger.info("应用启动完成")

@app.on_event("shutdown")
async def shutdown_event():
    """应用关闭时执行的操作"""
    logger.info("应用关闭中...")
    
    # 关闭备份任务调度器
    shutdown_backup_scheduler()
    
    # 应用关闭完成
    logger.info("应用关闭完成")